package com.gykj.redis.config;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.MapPropertySource;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;

@Configuration
public class RedisClusterConf {

	protected static Logger log = LoggerFactory.getLogger(RedisClusterConf.class);

	// Redis服务器地址
	@Value("${spring.redis.host}")
	private String host;
	
	@Value("${spring.redis.port}")
	private int port; 
	
	//集群机器
    @Value("${spring.redis.cluster.nodes}")
    private String clusterNodes;
    
    //连接超时时间（毫秒）
	@Value("${spring.redis.timeout}")
	private int timeout; 
	
	// Redis数据库索引(默认为0) 
	@Value("${spring.redis.database}")
	private int database; 
	
	// 连接池最大连接数（使用负值表示没有限制）
	@Value("${spring.redis.pool.max-active}")
	private int maxTotal; 
	
	// 连接池最大阻塞等待时间（使用负值表示没有限制）
	@Value("${spring.redis.pool.max-wait}")
	private int maxWaitMillis; 
	
	// 连接池中的最大空闲连接
	@Value("${spring.redis.pool.max-idle}")
	private int maxIdle; 
	
	// 连接池中的最小空闲连接
	@Value("${spring.redis.pool.min-idle}")
	private int minIdle; 
    
/*    @Bean(name = "jedisClusterConfig")
    public JedisCluster getJedisCluster() {
        String[] cNodes = clusterNodes.split(" ");
        Set<HostAndPort> nodes =new HashSet<>();
        //分割出集群节点
        for(String node : cNodes) {
            String[] hp = node.split(":");
            nodes.add(new HostAndPort(hp[0],Integer.parseInt(hp[1])));
        }
        JedisPoolConfig jedisPoolConfig =new JedisPoolConfig();
		jedisPoolConfig.setMaxTotal(this.maxTotal); // 连接池最大连接数（使用负值表示没有限制）
		jedisPoolConfig.setMaxWaitMillis(this.maxWaitMillis); // 连接池最大阻塞等待时间（使用负值表示没有限制）
		jedisPoolConfig.setMaxIdle(this.maxIdle); // 连接池中的最大空闲连接
		jedisPoolConfig.setMinIdle(this.minIdle); // 连接池中的最小空闲连接
        //创建集群对象
        return new JedisCluster(nodes,timeout,jedisPoolConfig);
    }*/
	
	@Bean(name = "jedisClusterConfig")
	public RedisClusterConfiguration getClusterConfiguration() {
		Map<String, Object> source = new HashMap<String, Object>();
		source.put("spring.redis.cluster.nodes", this.clusterNodes);
		source.put("spring.redis.cluster.timeout", this.timeout);
		source.put("spring.redis.cluster.max-redirects", 5);
		return new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source));
	}
	
	/**
	 * 实例化 RedisConnectionFactory 对象
	 * @param poolConfig
	 * @return
	 */
	@Bean(name = "jedisConnectionFactory")
	public RedisConnectionFactory jedisConnectionFactory(@Qualifier(value = "jedisClusterConfig") RedisClusterConfiguration jedisClusterConfig) {
		log.info("初始化RedisConnectionFactory");
		JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisClusterConfig);
		jedisConnectionFactory.setHostName(this.clusterNodes);
		jedisConnectionFactory.setPort(this.port);
		jedisConnectionFactory.setDatabase(this.database);
		return jedisConnectionFactory;
	}
	 
	/**
	 * 实例化 RedisTemplate 对象
	 * @return
	 */
	@Bean(name = "redisTemplate")
	public RedisTemplate<String,Object> functionDomainRedisTemplate(@Qualifier(value = "jedisConnectionFactory") RedisConnectionFactory factory) {
		log.info("初始化RedisTemplate");
		RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
		redisTemplate.setConnectionFactory(factory);
		
/*		redisTemplate.setKeySerializer(new StringRedisSerializer());
		redisTemplate.setHashKeySerializer(new StringRedisSerializer());
		redisTemplate.setHashValueSerializer(new EntityRedisSerializer());
		redisTemplate.setValueSerializer(new EntityRedisSerializer());*/
		
		//key序列化方式,但是如果方法上有Long等非String类型的话，会报类型转换错误
		redisTemplate.setKeySerializer(new StringRedisSerializer());//Long类型不可以会出现异常信息;
		redisTemplate.setHashKeySerializer(new StringRedisSerializer());
		redisTemplate.setValueSerializer(new GenericFastJsonRedisSerializer());
		redisTemplate.setHashValueSerializer(new GenericFastJsonRedisSerializer());
		
		//打开autotype功能
		ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
		
		redisTemplate.afterPropertiesSet();
		redisTemplate.setEnableTransactionSupport(true);
		return redisTemplate;
	}
	
}
